Skip to content

fix: review follow-ups — Arch default for at-spi fallback, input-backend degradation logging, test cleanups - #11

Merged
VibeProgramm merged 4 commits into
mainfrom
fix/review-followups
Sep 6, 2026
Merged

fix: review follow-ups — Arch default for at-spi fallback, input-backend degradation logging, test cleanups#11
VibeProgramm merged 4 commits into
mainfrom
fix/review-followups

Conversation

@VibeProgramm

Copy link
Copy Markdown
Owner

Контекст: PR #10 (порт 3 фиксов из upstream isac322#42, релиз v0.8.1). Верификация выявила 2 minor + 3 nit + типовые замечания. Этот PR исправляет ровно перечисленные находки, ничего сверх.

Находки верификации и исправления

1. session.py — финальный фолбэк резолвера at-spi-bus-launcher (minor)

Находка: последний фолбэк _at_spi_bus_launcher() возвращал _AT_SPI_LAUNCHER_CANDIDATES[0] (/usr/libexec/..., Debian/Ubuntu/Fedora-путь), а спека issue #8 требует «затем дефолт Arch». На Arch такой фолбэк — мёртвый путь в bash-обёртке.
Исправлено: фолбэк — литерал _AT_SPI_LAUNCHER_FALLBACK = "/usr/lib/at-spi-bus-launcher" (литерал вместо candidates[1]: индекс молча переплыл бы при реордеринге кандидатов — комментарий в коде). Тест test_at_spi_launcher_falls_back_to_which теперь ожидает Arch-дефолт (раньше фиксировал неверное поведение — assert на /nonexistent/a).
Мутационная проверка: временно вернул candidates[0] — тест упал; вернул — зелёный.

2. core.py — причина деградации input backend глоталась молча (minor)

Находка: в session_start и session_connect except RuntimeError: без лога — «почему нет input backend» терялось.
Исправлено: в обеих точках перед деградацией logger.warning(...) с текстом исключения. Механизм: в пакете логирования нет вовсе (grep по logging|getLogger пуст), tool_error не подходит (он бросает ToolError, а деградация — не ошибка); выбран stdlib logging → stderr, стандартный канал для stdio-MCP (stdout занят протоколом). Само поведение деградации (выбор бэкенда) не изменено.
Проверка: runtime-скрипт с заглушкой InputBackend, бросающей RuntimeError — результат session_start прежний ("No input backend available"), warning с текстом причины пойман хендлером.

3. session.py — путь в bash-обёртку без кавычек (nit)

Находка: {_at_spi_bus_launcher()} --launch-immediately интерполировался без кавычек.
Исправлено: shlex.quote(...) (+ import). Отклонение от ожидания инструкции: shlex.quote не добавляет кавычек путям без спецсимволов, поэтому тест оставлен на прежнюю подстроку без кавычек и дополнен вторым кейсом /opt/my tools/launcher, где кавычки реально появляются — так тест честен и покрывает кавычки.

4. tests/test_input_eis_error.py — мёртвое присваивание (nit)

Находка: client = _client_with_bus(object()) немедленно перетирался.
Исправлено: строка удалена (проверено: _client_with_bus — чистая заглушка конструктора, без side effects).

5. tests/test_screenshot_fallback.py — таутология (nit)

Находка: assert Image всегда истинен.
Исправлено: тест проверял реальное поведение (пропуск пустых фреймов), поэтому ассерт заменён на содержательный: phase 2 не вызывает Image.frombytes для пропущенного пустого фрейма (monkeypatch-счётчик, saved == []). Соседние сценарии не тронуты, тест-счётчик не уменьшился.

6. Type hints в тестах #10 (typo-level)

Находка: CONTRIBUTING требует хинты на всех сигнатурах; новые хелперы из PR #10 частично без хинтов.
Исправлено: fake_dbus/failing_dbus (address: str, path: Path -> Path), fake_spectacle/failing_spectacle (output_path: Path -> None), fake_raw_frame, monkeypatch: pytest.MonkeyPatch, tmp_path: Path в обоих файлах + сигнатура test_setup_translates_connect_failure_from_interface_proxy. Фикстуры-параметры в test_session_startup.py не хинтил — против конвенции файла (соседние тесты их не хинтят). Пре-экзистинг тесты вне диффа #10 не тронуты.

Релиз v0.8.2

CHANGELOG (2 user-facing fixed + 1 internal), pyproject 0.8.2, uv lock, scripts/sync_plugin_version.py (3 манифеста, --check зелёный), README v0.8.1 → v0.8.2.

Проверка

  • uv run ruff check src/ tests/ — All checks passed
  • uv run ruff format --check . — 40 files already formatted
  • uv run ty check src/ — All checks passed
  • uv run pytest tests/ -q65 passed (до: 65; тауологичный тест не удалён — заменён ассерт)
  • Мутационная проверка фиксa 1: сломано → тест падает → восстановлено (см. выше)

…uote it in the wrapper

The final fallback of _at_spi_bus_launcher returned candidates[0]
(/usr/libexec, the Debian/Ubuntu/Fedora layout), which does not exist on
Arch — a session where neither a candidate file nor PATH lookup finds the
launcher embedded a dead path into the wrapper. The last resort is now
the Arch default /usr/lib/at-spi-bus-launcher (literal, not a candidate
index, so reordering candidates cannot repoint it).

The resolved path is shlex.quote'd when embedded into the bash wrapper;
shlex.quote leaves plain paths untouched, so behavior is unchanged on
typical distros.

Test updated to expect the Arch default; the wrapper test now also
covers a path that requires quoting.
…wing it

Both InputBackend failure sites (session_start, session_connect) caught
RuntimeError and silently degraded to 'no input backend' / ydotool, so
the actual reason (EIS unavailable, dbus failure, libei load error) was
lost. Each site now logs a warning with the exception text before
degrading; backend selection itself is unchanged.

kwin_mcp has no logging module anywhere else; logging-to-stderr is the
standard channel for stdio MCP servers whose stdout carries the
protocol.
…ints

- test_input_eis_error: dropped a dead _client_with_bus(object())
  assignment immediately overwritten by _client_with_bus(_OkBus());
  no side effects (pure constructor stub).
- test_screenshot_fallback: 'assert Image' was always true; replaced
  with a real assertion that phase 2 never calls Image.frombytes for
  the skipped empty frame.
- Type hints on fakes/helpers in both files (monkeypatch -> pytest.
  MonkeyPatch, tmp_path -> Path, fake signatures), per CONTRIBUTING
  style rules. Pre-existing tests outside the PR #10 diff untouched.
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

📝 Docs & SEO Review

Source files changed in this PR:

.claude-plugin/marketplace.json
integrations/claude-code/.claude-plugin/plugin.json
integrations/opencode/plugin/package.json
pyproject.toml
src/kwin_mcp/core.py
src/kwin_mcp/session.py

Consistency check results:

✅  All documentation/plugin SEO checks passed.

Run @docs-seo in Claude Code to perform a full documentation review.

@VibeProgramm
VibeProgramm merged commit 3bd880e into main Sep 6, 2026
9 checks passed
@VibeProgramm
VibeProgramm deleted the fix/review-followups branch September 6, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant